<template>
  <li class="jstree-node"
      :class="[isLeafItem ? 'jstree-leaf' : (data.opened ? 'jstree-open' : 'jstree-closed'), {'jstree-last': lastrow}]">
    <div class="jstree-wholerow"
         :class="[{'jstree-wholerow-clicked': data.selected, 'jstree-wholerow-hovered': hovered}]" v-if="wholerow">
      &nbsp;
    </div>
    <i class="jstree-icon jstree-ocl" @click="handleExpand"></i>
    <a class="jstree-anchor" :class="[{'jstree-clicked': data.selected, 'jstree-hovered':hovered}]"
       @click="handleItemClick" @mouseover="hovered = true" @mouseout="hovered = false">
      <i v-if="showCheckbox" class="jstree-icon jstree-checkbox" :class="[{'jstree-undetermined': indeterminate}]"></i>
      <i v-if="!!data.icon" class="jstree-icon jstree-themeicon icon-lg jstree-themeicon-custom" :class="data.icon"></i>
      <span v-html="data.title"></span>
    </a>
    <ul class="jstree-children" v-if="data.children && data.children.length">
      <tree-node
        v-for="(item, index) in data.children"
        :key="item"
        :data="item"
        :lastrow="(index + 1) === data.children.length"
        :wholerow="wholerow"
        :show-checkbox="showCheckbox"
        :multiple="multiple">
      </tree-node>
    </ul>
  </li>

</template>

<script>
  import Emitter from './emitter'
  import {findComponentsDownward} from './assist'

  export default {
    name: 'TreeNode',
    componentName: 'TreeNode',
    mixins: [Emitter],
    props: {
      data: {
        type: Object,
        default () {
          return []
        }
      },
      wholerow: {
        type: Boolean,
        default: false
      },
      showCheckbox: {
        type: Boolean
      },
      multiple: {
        type: Boolean,
        default: false
      },
      lastrow: {
        type: Boolean
      }
    },
    data () {
      return {
        indeterminate: false,
        hovered: false
      }
    },
    computed: {
      isLeafItem () {
        return !(this.data.children && this.data.children.length)
      }
    },
    methods: {
      handleExpand () {
        if (this.data.disabled) return
        this.$set(this.data, 'opened', !this.data.opened)
        this.dispatch('Tree', 'toggle-expand', this.data)
      },
      handleItemClick () {
        if (this.data.disabled) return
        if (this.showCheckbox) {
          this.handleCheck()
        } else {
          this.handleSelect()
        }
      },
      handleSelect () {
        const oldVal = !!this.data.selected
        if (oldVal) {
          this.data.selected = false
        } else if (this.multiple) {
          this.$set(this.data, 'selected', !this.data.selected)
        } else {
          this.dispatch('Tree', 'selected', this.data)
        }
        this.dispatch('Tree', 'on-selected')
      },
      handleCheck () {
        const selected = !this.data.selected
        if (selected) {
          findComponentsDownward(this, 'TreeNode').forEach(node => { node.data.selected = true })
        } else {
          findComponentsDownward(this, 'TreeNode').forEach(node => { node.data.selected = false })
        }

        this.data.selected = selected
        this.dispatch('Tree', 'checked')
        this.dispatch('Tree', 'on-selected')
      },
      setIndeterminate () {
        this.indeterminate = this.data.selected ? false : findComponentsDownward(this, 'TreeNode').some(node => node.data.selected)
      }
    },
    created () {
      // created node.vue first, mounted tree.vue second
      if (!this.data.selected) this.$set(this.data, 'selected', false)
    },
    mounted () {
      this.$on('indeterminate', () => {
        this.broadcast('TreeNode', 'indeterminate')
        this.setIndeterminate()
      })
    }
  }
</script>
